package com.nowar.common.service.impl;


import com.nowar.common.constant.Constant;
import com.nowar.common.service.MessageProvide;
import com.nowar.common.util.PropertyResolverHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Properties;

/**
 * @Author: 谢无殇。
 * @Date : 2023-01-29 21:39
 */
@Component
public class DefaultMessageProvide implements MessageProvide {

    private static final String UTF_8 = "UTF-8";
    private static final String PROPERTIES_SUFFIX = ".properties";
    private static final String CLASS_PATH = "classpath:";
    private static final String CLASSPATH_CONFIG = "classpath:config";
    private static final String CONFIG_PATH = "config";
    /**
     * 类资源下的文件
     */
    private ReloadableResourceBundleMessageSource messageSource;
    /**
     * 外部配置文件
     */
    private Properties properties;

    private Properties systemProperties;

    private ClassLoader classLoader = ClassUtils.getDefaultClassLoader();


    @PostConstruct
    public void init() {
        List<String> list = new ArrayList<>();
        getResourceFile(list);
        String[] baseNames = list.toArray(new String[list.size()]);
        ReloadableResourceBundleMessageSource messageSource = messageSource();
        messageSource.addBasenames(baseNames);
        this.messageSource = messageSource;
        loaderOutsideResource();
        //不为空则放入资源加载器中
        if (this.properties != null) {
            this.messageSource.setCommonMessages(this.properties);
            //this.messageSource.setPropertiesPersister();
        }
    }

    private void getResourceFile(List<String> list) {
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource(CLASSPATH_CONFIG);
        if (resource == null) {
            return;
        }
        try {
            String path = resource.getURL().getPath();
            if (StringUtils.isEmpty(path)) {
                return;
            }
            File file = new File(path);
            getClassPath(list, file);
        } catch (IOException e) {
            System.out.println("日志打印");
            e.printStackTrace();
        }
    }

    private void getClassPath(List<String> list, File file) {
        if (!file.exists()) {
            return;
        }
        if (file.isFile()) {
            if (file.getName().contains(PROPERTIES_SUFFIX)) {
                String path = file.getPath();
                path = path.substring(path.indexOf(CONFIG_PATH + File.separator), path.indexOf(PROPERTIES_SUFFIX));
                // todo
                list.add(path);
            }
            return;
        }
        for (File f : file.listFiles()) {
            getClassPath(list, f);
        }
    }

    private void getProperties() {
        if (this.properties == null) {
            this.properties = new Properties();
        }
    }

    @Override
    public String getMessage(String code) {
        return messageSource.getMessage(code, null, Locale.CHINA);
    }

    @Override
    public String getMessage(String code, Locale locale) {

        return messageSource.getMessage(code, null, locale);
    }

    @Autowired
    private Environment environment;

    @Override
    public String getValueProperties(String text) {
        if (systemProperties == null) {
            //获取环境的所有变量
            systemProperties = System.getProperties();
            systemProperties.putAll(System.getenv());
        }
        String value = PropertyResolverHelper.getValueByProperties(text, systemProperties);
        if (!StringUtils.isEmpty(value) && !value.contains(Constant.DEFAULT_PLACEHOLDER_PREFIX)) {
            return value;
        }
        value = environment.resolvePlaceholders(text);
        if (!StringUtils.isEmpty(value) && !value.contains(Constant.DEFAULT_PLACEHOLDER_PREFIX)) {
            return value;
        }
        //todo
        if (properties == null) {
            init();
        }
        value = PropertyResolverHelper.getValueByProperties(text, properties);
        return value;
    }

    private ReloadableResourceBundleMessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        //messageSource.addBasenames("classpath:proxy/test");
        messageSource.setDefaultEncoding(UTF_8);
        messageSource.setUseCodeAsDefaultMessage(true);
        messageSource.setCacheMillis(-1);
        return messageSource;
    }

    private void loaderOutsideResource() {
        URL url = classLoader.getResource("");
        if (url == null) {
            return;
        }
        String path = url.getPath();
        String configPath = "";
        while (path.contains(File.separator)) {
            path = path.substring(0, path.lastIndexOf(File.separator));
            configPath = path + File.separator + CONFIG_PATH;
            File file = new File(configPath);
            if (file.exists()) {
                getConfigProperties(file);
                return;
            }
        }
    }

    private void getConfigProperties(File file) {
        if (file == null) {
            return;
        }
        if (!file.exists()) {
            return;
        }
        getProperties();
        if (file.isFile()) {
            if (file.getName().contains(PROPERTIES_SUFFIX)) {
                try (FileInputStream fileInputStream = new FileInputStream(file)) {
                    this.properties.load(fileInputStream);
                } catch (IOException e) {
                    System.out.println("日志打印");
                }
            }
            return;
        }
        for (File f : file.listFiles()) {
            getConfigProperties(f);
        }
    }

}
